/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gace.dao;

import gace.basededatos.Conexion;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import gace.logica.Habitacion;
import gace.logica.Renta;
import gace.logica.Reserva;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.sql.Date;
import java.util.Calendar;

/**
 *
 * @author Cast-Valv-HP
 */
public class HabitacionDao {

    private Connection conexion;

    public HabitacionDao() throws SQLException{
        this.conexion = (Connection) Conexion.getConexion();
    }
    

    /**
     *
     * @param r1 Objeto de tipo Reserva, necesario para conocer las fechas de reserva
     * y asi poder conocer las habitaciones disponibles.
     * @return Lista de habitaciones disponibles
     * @throws SQLException
     */
    public ArrayList<Habitacion> listarHabitaciones(Date fechaInicio, Date fechaFin) throws SQLException{

        /* checar habitaciones disponibles descartando las habitaciones de
        las reservas ya hechas */
        String sql = "select * from reserva";
        PreparedStatement stmt = conexion.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        rs.last();
        int numReservas = rs.getRow();
        rs.close();
        stmt.close();

        ArrayList<Integer> miLista = new ArrayList<Integer>();

        // Si no hay reservas, todas las habitaciones estan disponibles
        if (numReservas == 0){
            System.out.println("Hola!");
            String sql2 = "select * from habitacion";
            PreparedStatement stmt2 = conexion.prepareStatement(sql2);
            ResultSet rs2 = stmt2.executeQuery();

            while(rs2.next()){
                miLista.add(rs2.getInt("idhabitacion"));
            }
            rs2.close();
            stmt2.close();
        }
        /* Si hay reservas, se deben checar las fechas de inicio y fin de las
        reservas para poder conocer la disponbilidad real de habitaciones*/
        else{
            // Las habitaciones ocupadas por reservas
            String sql3 = "select * from reserva_habitacion left join reserva on "
                    + "reserva_habitacion.reserva_idreserva = reserva.idreserva "
                    + "where (fechaInicio <  ? or fechaInicio < ?) "
                    + "and (fechaFin >  ? or fechaFin > ?) ";
            PreparedStatement stmt3 = conexion.prepareStatement(sql3);
            stmt3.setDate(1, (Date) fechaInicio);
            stmt3.setDate(2, (Date) fechaFin);
            stmt3.setDate(3, (Date) fechaInicio);
            stmt3.setDate(4, (Date) fechaFin);
            ResultSet rs3 = stmt3.executeQuery();
            System.out.println("hey");
            while(rs3.next()){
                miLista.add(rs3.getInt("habitacion_idhabitacion"));
                
            }

            rs3.close();
            stmt3.close();
        }

        /* checar habitaciones disponibles descartando las habitaciones de las
        rentas ya hechas */

        String sqlRenta = "select * from renta";
        PreparedStatement stmtRenta = conexion.prepareStatement(sqlRenta);
        ResultSet rsRenta = stmtRenta.executeQuery();
        rsRenta.last();
        int numRentas = rsRenta.getRow();
        stmtRenta.close();

        ArrayList<Integer> miListaRenta = new ArrayList<Integer>();

        // Si no hay rentas, todas las habitaciones estan disponibles
        if (numRentas == 0){
            String sql2 = "select * from habitacion";
            PreparedStatement stmt2 = conexion.prepareStatement(sql2);
            ResultSet rs2 = stmt2.executeQuery();

            while(rs2.next()){
                miListaRenta.add(rs2.getInt("idhabitacion"));
            }
            rs2.close();
            stmt2.close();
        }
        /* Si hay rentas, se deben checar las fechas de inicio y fin de las
        mismas para poder conocer la disponbilidad real de habitaciones*/
        else{
            // habitaciones ocupadas por rentas
            String sql3 = "select * from habitacion_renta left join renta on "
                    + "habitacion_renta.renta_idrenta = renta.idrenta "
                    + "where (fechaInicio <  ? or fechaInicio < ?) "
                    + "and (fechaFin >  ? or fechaFin > ?) ";
            PreparedStatement stmt3 = conexion.prepareStatement(sql3);
            stmt3.setDate(1, (Date) fechaInicio);
            stmt3.setDate(2, (Date) fechaFin);
            stmt3.setDate(3, (Date) fechaInicio);
            stmt3.setDate(4, (Date) fechaFin);
            ResultSet rs3 = stmt3.executeQuery();

            while(rs3.next()){
                miListaRenta.add(rs3.getInt("habitacion_idhabitacion"));
            }

            rs3.close();
            stmt3.close();
        }

        String sqlHab = "select * from habitacion";
        PreparedStatement stmtHab = conexion.prepareStatement(sqlHab);
        ResultSet rsHab = stmtHab.executeQuery();
        ArrayList<Habitacion> hab = new ArrayList<Habitacion>();
        ArrayList<Integer> habNum = new ArrayList<Integer>();
        while(rsHab.next()){
            Habitacion h1 = new Habitacion();
            h1.setNumHabitacion(rsHab.getInt("idhabitacion"));
            h1.setTipo(rsHab.getString("tipo"));
            h1.setIdServicio(rsHab.getInt("idservicio"));
            habNum.add(rsHab.getInt("idhabitacion"));
            hab.add(h1);
        }

        for (Habitacion h : hab) {
            System.out.println(h.getNumHabitacion());
        }

        /* sacar de las listas de habitaciones en "hab" las habitaciones
         contenidas en miLista y miListaRenta, que corresponden a las
         habitaciones ocupadas por reservas y por rentas en las fechas
         de la reserva que se pasa como parametro a este metodo*/

        int longLista1 = miLista.size();
        int longLista2 = miListaRenta.size();
        System.out.println(longLista1 + " : " + longLista2);

        for (Integer hj : miLista) {
            if(habNum.contains(hj)){
                habNum.remove(hj);
            }
        }

        for (Integer hj : miListaRenta) {
            if(habNum.contains(hj)){
                habNum.remove(hj);
            }
        }


        ArrayList<Habitacion> habCopy = (ArrayList<Habitacion>) hab.clone();
        for (Habitacion h : habCopy) {
            if(!habNum.contains(h.getNumHabitacion())){
                hab.remove(h);

            }
        }

        return hab;
    }

    public static void main(String[] args) throws SQLException{
        HabitacionDao hDao = new HabitacionDao();
        Calendar cal = Calendar.getInstance();
        cal.set(2011, 4, 8);
        Date fechaInicio = new Date(cal.getTimeInMillis());
        cal.set(2011, 4, 9);
        Date fechaFin = new Date(cal.getTimeInMillis());
        System.out.println(fechaInicio.toString());
        ArrayList<Habitacion> hab3 = hDao.listarHabitaciones(fechaInicio, fechaFin);
        for (Habitacion h : hab3) {
            System.out.println(h.getNumHabitacion());
        }

    }

}